#include "RingQueue.hpp"
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <ctime>
#include <string>

template<class T>
class ThreadData{
public:
    RingQueue<T> *_rq;
    std::string _threadname;
};

// 生产者 
void *Producter(void *args){
    ThreadData<int> *td = static_cast<ThreadData<int> *>(args);
    RingQueue<int> *rq = td->_rq;
    std::string threadname = td->_threadname;
    while (true)
    {
        sleep(1);
        // 1.获取数据
        int data = rand() % 10 + 1;
  
        // 2.生产数据
        rq->push(data);
        std::cout << "Producter data done, data is: " << data << " who: " << threadname << std::endl;
    }
    delete td;  // 在线程结束时释放 ThreadData 对象
    return nullptr;
}

// 消费者
void *Consumer(void *args){
    ThreadData<int> *td = static_cast<ThreadData<int> *>(args);
    RingQueue<int> *rq = td->_rq;
    std::string threadname = td->_threadname;
    while(true){
        //sleep(1);
        // 1.消费数据
        int data = 0;
        rq->pop(&data);

        // 2.处理数据
        data++;
        std::cout << "Consumer get a data, data is: " << data << " who: " << threadname << std::endl;
    }
    delete td;  // 在线程结束时释放 ThreadData 对象
    return nullptr;
}

int main(){
    srand(time(nullptr));
    RingQueue<int> *rq = new RingQueue<int>();

    // 单生产单消费：
    // pthread_t c, p;
    // ThreadData<int> *c_td = new ThreadData<int>();
    // c_td->_rq = rq;
    // c_td->_threadname = "Consumer";
    // pthread_create(&c, nullptr, Consumer, c_td);

    // ThreadData<int> *p_td = new ThreadData<int>();
    // p_td->_rq = rq;
    // p_td->_threadname = "Producter";
    // pthread_create(&p, nullptr, Producter, p_td);

    // pthread_join(c, nullptr);
    // pthread_join(p, nullptr);
    // delete c_td;
    // delete p_td;


    // 多生产多消费：
    pthread_t c[3], p[5];
    for (int i = 0; i < 3; i++){
        ThreadData<int> *c_td = new ThreadData<int>();
        c_td->_rq = rq;
        c_td->_threadname = "Consumer-" + std::to_string(i);
        pthread_create(c + i, nullptr, Consumer, c_td);
    }
    for (int i = 0; i < 5; i++){
        ThreadData<int> *p_td = new ThreadData<int>();
        p_td->_rq = rq;
        p_td->_threadname = "Producter-" + std::to_string(i);
        pthread_create(p + i, nullptr, Producter, p_td);
    }

    // 等待回收所有线程
    for (int i = 0; i < 3; i++){
        pthread_join(c[i], nullptr);
    }
    for (int i = 0; i < 5; i++){
        pthread_join(p[i], nullptr);
    }


    delete rq;
    return 0;
}